package com.cskaoyan.javase.oop3._1interface._0introduction;

/**
 * 现在我们有了新需求：
 * 一部分猫和狗，经过了特殊训练，能够直立行走了。那么这群特殊的猫和狗，怎么描述它们呢？
 *
 * 分析：
 * 部分猫和狗经过特殊训练，才能够直立行走。所以不可能直接加个方法到Cat类和Dog类中，不是所有猫狗都有这个行为。
 *
 * 而特殊的猫狗仍然是猫和狗，所以它们肯定还要继承猫和狗这两个类。
 * 可能很多同学，这时候想到的就是：重新定义两个新的猫狗类（比如超级狗和猫）继承猫狗，然后给出直立行走的方法就算完事了。
 * 这样做不是不行，需求是实现了，但还有一些小问题：
 * 一方面没有体现代码复用。
 * 更重要的是，没有体现出特殊训练的过程。
 * 假如还有一些动物也要直立行走，增加这个行为，如何体现出规范性、标准性呢？
 * 体现出它们是特殊的经过训练的动物呢？
 *
 * 这里我们想到了抽象类，因为抽象类中抽象方法，可以强制约束子类实现它，这样就是一种标准和规范，体现了它经过了特殊训练，和之前不同了。
 *
 * 于是我们定义抽象类，给出抽象方法，让超级猫狗类去继承这个抽象类，可行吗？
 *
 * 理想很美好，现实很骨感。显然做不到，因为Java不支持多继承。
 * 除开这点这么做也不是完美的，问题是：
 *
 * 这个抽象类里面是对功能和行为的抽象，缺少属性（单独一个直立行走的行为是一个什么对象？）所以单独的行为不应该被抽象为类，不符合类的定义。
 * 继承这个抽象类也不符合继承的"is-a"关系，这里不适用继承（还是上面那句话，行为根本不是个体）
 * 于是，我们就迫切需要一种全新的数据类型，这种全新的数据类型：
 *
 *      1.不强调属性，只强调行为的抽象，"继承"它表示功能的扩展。
 *      2.在一个类继承某个类后，还能继续"继承"，不受Java单继承限制。
 *      3.没有"is-a"这种继承关系的限制。
 *      4.最好还有抽象方法。（因为它能表示规范和标准）
 * 这种全新的数据类型，就是接口（interface）。
 *
 * 接口的概述:
 * 上面四条，其实已经描述了接口的特点，
 * 接口是一种表示对行为抽象的，不受Java单继承限制的，用来作为功能扩展标准的一种引用数据类型。
 * 它的定义语法如下：
 * [访问权限修饰符] interface 接口名{
 *     // 接口体
 * }
 * 解释:
 *      1.接口的访问权限修饰符也只有两种,和class一模一样.
 *      2.interface是一个关键字,和class类似,表示声明接口.
 *      接口和class是同等级别的数据类型
 *      它们都是引用数据类型
 *
 *      3.接口名和类名一样，遵循大驼峰式的书写规范，接口名最好起的见名知意。
 *      接口的命名,有些程序员喜欢用"I"开头,表示这是一个接口.(这不是强制的)
 *      4.接口中可以定义抽象方法，和抽象类中定义的抽象方法,在使用上没有区别。
 *
 * 接口的使用
 *      1.接口是可以被一个类"继承"的.
 *      接口的"继承"，更准确、常见的叫法称之为接口的实现.当然它也不再使用extends关键字，而是使用 implements 关键字。
 *
 *      2.一个类如果已经继承了别的类
 *      那么应该先继承,再实现,顺序是不能变的
 *      语法:
 *      [访问权限修饰符] class 类名 extends 类名 implements 接口名 {}
 *      普通类实现接口,必须实现接口中所有抽象方法
 *
 *      3. 在接口的实现中，可以称呼接口为"父接口"，接口的实现类为"子类"，它们仍然是父子关系。
 *      当然多态现象仍然能够发生。
 *      也就是说实现和继承虽然用的关键字不同
 *      但本质是一样的
 *      其实都是继承,还是父子类
 *
 *      4.接口不受多继承限制，一个类可以在继承别的类的同时实现接口，而且可以实现多个接口。
 *      一个类可以实现多个接口,而不是只能实现一个.
 *
 * 使用接口的优点:
 * 1.接口不受单继承限制，这是接口非常重要的优点。
 * 2.接口不是类，它和它的实现类，也不需要存在"is-a"关系，接口比抽象类的使用更加灵活。
 * 接口的使用也会更加常见.
 * 3.程序开发中将接口和它的实现类之间的关系
 * 称之为"like-a"关系。
 * 只要是实现了Xxx的功能，就像Xxx。
 *
 * 比如给一个盒子
 * 让这个盒子实现制热和制冷这两个空调的功能
 * 那么它虽然不是空调,但它像一个空调.
 *
 * 接口表示一种开发标准，一种规范。
 * 表示对功能的扩展，它只关注行为，不关注属性。
 *
 * @since 09:33
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 引用的数据类型决定了引用的访问范围
        SuperCat sc = new SuperCat();
        sc.test();
        sc.shout();
        sc.testCat();
        Cat c = new SuperCat();
        c.shout();
        ISkills is = new SuperCat();
        is.test();
        is.walkUpright();
    }
}

abstract class Animal {
    public abstract void shout();
}

class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}

class SuperCat extends Cat implements ISkills, IA {
    @Override
    public void walkUpright() {
        System.out.println("我是超威蓝猫,我一直都是站着走!");
    }

    @Override
    public void test() {
    }

    public void testCat() {
    }
}

class SuperDog extends Dog implements ISkills {
    @Override
    public void walkUpright() {
        System.out.println("我是汪汪队,我一直都是站着走!");
    }

    @Override
    public void test() {
    }
}

abstract class AbstractSkills {
    public abstract void walkUpright();
}

interface ISkills {
    public abstract void walkUpright();

    public abstract void test();

}

interface IA {
}